package com.lz.sentinel.common.exception;

import cn.hutool.core.util.StrUtil;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import com.lz.sentinel.common.entity.ResponseVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import java.nio.file.AccessDeniedException;
import java.sql.SQLException;


/**
 * 全局异常处理器
 *
 * @author xpp
 */
@RestControllerAdvice
public class GlobalExceptionHandler {
    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 权限校验异常
     */
    @ExceptionHandler(AccessDeniedException.class)
    public ResponseVo handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request) {
        e.printStackTrace();

        return ResponseVo.failure("");
    }

    /**
     * 请求方式不支持
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public ResponseVo handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, HttpServletRequest request) {
        e.printStackTrace();
        String requestURI = request.getRequestURI();

        return ResponseVo.failure("");
    }
    /**
     * 替换默认流控提示内容:Blocked by sentinel(flow limiting)
     * 流控规则异常处理
     * 如果 @SentinelResource中定义了 blockHandler 和 faidback 属性，则此处不会捕获，以为 blockHandler 和 failback的优先级最高。
     *
     */
    @ExceptionHandler({BlockException.class})
    public ResponseVo handleRRException(BlockException e){
        logger.error(e.getMessage());
        return ResponseVo.failure("BlockException");
    }

    /**
     * 替换默认流控提示内容:Blocked by sentinel(flow limiting)
     * 流控规则异常处理
     * 如果 @SentinelResource中定义了 blockHandler 和 faidback 属性，则此处不会捕获，以为 blockHandler 和 failback的优先级最高。
     *
     */
    @ExceptionHandler({FlowException.class})
    public ResponseVo handleRRException(FlowException e){
        logger.error(e.getMessage());
        return ResponseVo.failure("FlowException");
    }

    /**
     * 服务降级异常处理
     */
    @ExceptionHandler({DegradeException.class})
    public ResponseVo handleRRException(DegradeException e){
        logger.error(e.getMessage());
        return ResponseVo.failure("DegradeException");
    }

    /**
     * 处理流量控制异常处理
     */
    @ExceptionHandler({AuthorityException.class})
    public ResponseVo handleRRException(AuthorityException e){
        logger.error(e.getMessage());
        return ResponseVo.failure("AuthorityException");
    }

    /**
     * 处理流量控制异常处理
     */
    @ExceptionHandler({ParamFlowException.class})
    public ResponseVo handleRRException(ParamFlowException e){
        logger.error(e.getMessage());
        return ResponseVo.failure("ParamFlowException");
    }

    /**
     * 处理流量控制异常处理
     */
    @ExceptionHandler({SystemBlockException.class})
    public ResponseVo handleRRException(SystemBlockException e){
        logger.error(e.getMessage());
        return ResponseVo.failure("SystemBlockException");
    }


}
